home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / 25 user and custom controls / customcontrollibrary / multiplierex.vb < prev    next >
Encoding:
Text File  |  2002-03-19  |  7.0 KB  |  201 lines

  1. ' The MultiplierEx custom control shows how you can implement 
  2. ' client-side JavaScript routines and associate them with a control
  3.  
  4. ' This source code is very similar to the Multiplier control, except that
  5. ' the Button class now refers to a nested class that renders the 
  6. ' necessary attribute for the button.
  7.  
  8. Imports System.ComponentModel
  9. Imports System.Web.UI
  10. Imports System.Web.UI.WebControls
  11.  
  12. <ToolboxData("<{0}:MultiplierEx runat=server></{0}:MultiplierEx>")> _
  13. Public Class MultiplierEx
  14.     Inherits System.Web.UI.WebControls.WebControl
  15.     Implements INamingContainer
  16.  
  17.     ' These variables hold the control.
  18.     Dim txtFirst As TextBox
  19.     Dim txtSecond As TextBox
  20.     Dim txtResult As TextBox
  21.     Dim WithEvents btnEval As Button
  22.  
  23.     Sub New()
  24.         MyBase.New()
  25.         Me.Width = Unit.Pixel(200)
  26.     End Sub
  27.  
  28.     ' ALl controls that rely on client-side features should implement this property
  29.  
  30.     Property EnableClientScript() As Boolean
  31.         Get
  32.             Dim o As Object = Me.ViewState("EnableClientScript")
  33.             If o Is Nothing Then
  34.                 Return True
  35.             Else
  36.                 Return CBool(o)
  37.             End If
  38.         End Get
  39.         Set(ByVal Value As Boolean)
  40.             Me.ViewState("EnableClientScript") = Value
  41.         End Set
  42.     End Property
  43.  
  44.     ' this code is very similar to the code in Multiplier control
  45.  
  46.     Protected Overrides Sub CreateChildControls()
  47.         'Create all child controls .
  48.         txtFirst = New TextBox()
  49.         txtSecond = New TextBox()
  50.         btnEval = New Button()
  51.         txtResult = New TextBox()
  52.         Dim lblAsterisk As New Label()
  53.  
  54.         ' Set their properties
  55.         lblAsterisk.Text = " * "
  56.         btnEval.Text = " = "
  57.         txtResult.ReadOnly = True
  58.  
  59.         ' this is necessary to achieve syntactically correct ID properties.
  60.         txtFirst.ID = txtFirst.ClientID
  61.         txtSecond.ID = txtSecond.ClientID
  62.         txtResult.ID = txtResult.ClientID
  63.  
  64.         ' Establish correct width for text controls.
  65.         AdjustControlWidth()
  66.  
  67.         ' Add to the controls collection.
  68.         Controls.Add(txtFirst)
  69.         Controls.Add(lblAsterisk)
  70.         Controls.Add(txtSecond)
  71.         Controls.Add(btnEval)
  72.         Controls.Add(txtResult)
  73.     End Sub
  74.  
  75.     <Browsable(False)> _
  76.     Property Result() As Double
  77.         Get
  78.             EnsureChildControls()
  79.             Try
  80.                 Return CDbl(txtResult.Text)
  81.             Catch
  82.                 Return 0
  83.             End Try
  84.         End Get
  85.         Set(ByVal Value As Double)
  86.             EnsureChildControls()
  87.             txtResult.Text = Value.ToString
  88.         End Set
  89.     End Property
  90.  
  91.     Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
  92.         ' Ensure the child controls exist and then render them.
  93.         EnsureChildControls()
  94.         RenderChildren(output)
  95.         ' Adjust their width.
  96.         AdjustControlWidth()
  97.     End Sub
  98.  
  99.     ' Adjust controls' width.
  100.     Private Sub AdjustControlWidth()
  101.         ' Evaluate the space available for the three textboxes.
  102.         Dim w As Unit = Unit.Pixel(CInt(Me.Width.Value - 50) \ 3)
  103.         txtFirst.Width = w
  104.         txtSecond.Width = w
  105.         txtResult.Width = w
  106.     End Sub
  107.  
  108.     Private Sub btnEval_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEval.Click
  109.         EnsureChildControls()
  110.         Try
  111.             Dim res As Double = CDbl(txtFirst.Text) * CDbl(txtSecond.Text)
  112.             txtResult.Text = res.ToString
  113.         Catch
  114.             txtResult.Text = "# ERR #"
  115.         End Try
  116.     End Sub
  117.  
  118.     ' this nested class inherits from Button, but overrides its Render method
  119.  
  120.     Friend Class Button
  121.         Inherits System.Web.UI.WebControls.Button
  122.  
  123.         ' this is where we do the magic
  124.  
  125.         Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
  126.             ' If client scripts are disabled then render as usual and exit.
  127.             If Not IsClientScriptEnabled() Then
  128.                 MyBase.Render(writer)
  129.                 Exit Sub
  130.             End If
  131.  
  132.             ' Get a reference to the parent control.
  133.             Dim parCtrl As MultiplierEx = DirectCast(Me.Parent, MultiplierEx)
  134.  
  135.             ' prepare the code that invokes the script
  136.             Dim scriptInvoke As String = String.Format("javascript:MultiplierExecute({0},{1},{2});", _
  137.                 parCtrl.txtFirst.ClientID, parCtrl.txtSecond.ClientID, parCtrl.txtResult.ClientID)
  138.  
  139.             ' output the standard attributes.
  140.             writer.AddAttribute("type", "button")
  141.             writer.AddAttribute("name", Me.ClientID)
  142.             writer.AddAttribute("value", Me.Text)
  143.             ' output the onClick attribute.
  144.             writer.AddAttribute("onClick", scriptInvoke)
  145.  
  146.             ' enclose attributes in <input> tag.
  147.             writer.RenderBeginTag("input")
  148.             writer.RenderEndTag()
  149.         End Sub
  150.  
  151.         ' we output the JavaScript code in the OnPreRender method
  152.  
  153.         Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
  154.             ' Nothing to do if client scripts are disabled.
  155.             If Not IsClientScriptEnabled() Then Exit Sub
  156.  
  157.             ' Prepare the script routine.
  158.             Dim s As String
  159.             s &= "<script language=""javascript""><!--{0}" & ControlChars.CrLf
  160.             s &= "function MultiplierExecute(txt1, txt2, txt3) {" & ControlChars.CrLf
  161.             s &= "   var op1 = parseFloat( txt1.value );" & ControlChars.CrLf
  162.             s &= "   var op2 = parseFloat( txt2.value );" & ControlChars.CrLf
  163.             s &= "   txt3.value = (op1 * op2).toString(); " & ControlChars.CrLf
  164.             s &= "   }" & ControlChars.CrLf
  165.             s &= "--></script>" & ControlChars.CrLf
  166.             ' register the script on the page.
  167.             Page.RegisterClientScriptBlock("MultiplierExecute", s)
  168.  
  169.         End Sub
  170.  
  171.         ' Return True if client script support is requested and possible.
  172.         ' this routine can be easily reused in other applications
  173.  
  174.         Private Function IsClientScriptEnabled() As Boolean
  175.             ' we need a Try block because accessing the Browser
  176.             ' property at design time may throw
  177.             Try
  178.                 ' Return False if DOM version is too low.
  179.                 If Page.Request.Browser.W3CDomVersion.Major < 1 Then
  180.                     Return False
  181.                 End If
  182.  
  183.                 ' Return False if EcmaScript version is too low.
  184.                 If Page.Request.Browser.EcmaScriptVersion.CompareTo(New Version(1, 2)) < 0 Then
  185.                     Return False
  186.                 End If
  187.  
  188.                 ' if all tests passed, return the EnableClientScript property of its parent
  189.                 Dim parCtrl As MultiplierEx = DirectCast(Me.Parent, MultiplierEx)
  190.                 IsClientScriptEnabled = parCtrl.EnableClientScript
  191.             Catch
  192.                 ' return False if any error occurs
  193.                 Return False
  194.             End Try
  195.         End Function
  196.  
  197.     End Class
  198.  
  199. End Class
  200.  
  201.